package com.dcrzl.shcz.module.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.dcrzl.shcz.common.dto.UpdatePasswordDto;
import com.dcrzl.shcz.common.entity.info.Gov;
import com.dcrzl.shcz.common.entity.info.GovUnit;
import com.dcrzl.shcz.common.entity.info.MiniUserUnit;
import com.dcrzl.shcz.common.entity.sys.MiniUser;
import com.dcrzl.shcz.common.entity.sys.SysUser;
import com.dcrzl.shcz.common.enums.UserTypeEnum;
import com.dcrzl.shcz.common.exception.MyException;
import com.dcrzl.shcz.common.mapper.sys.MiniUserMapper;
import com.dcrzl.shcz.common.service.impl.BaseServiceImpl;
import com.dcrzl.shcz.common.utils.*;
import com.dcrzl.shcz.module.info.service.MiniUserUnitService;
import com.dcrzl.shcz.module.sys.service.MiniUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.io.Serializable;
import java.util.*;

@Service("miniUserService")
public class MiniUserServiceImpl extends BaseServiceImpl<MiniUserMapper, MiniUser> implements MiniUserService {

    @Autowired
    private MiniUserUnitService miniUserUnitService;

    private LambdaQueryWrapper<MiniUser> commonWrapper(MiniUser miniUser) {
        LambdaQueryWrapper<MiniUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Objects.nonNull(miniUser.getId()), MiniUser::getId, miniUser.getId());
        return wrapper;
    }

    @Override
    public Result<MiniUser> selectOne(MiniUser miniUser) {
        LambdaQueryWrapper<MiniUser> wrapper = this.commonWrapper(miniUser);
        wrapper.eq(Objects.nonNull(miniUser.getUsername()), MiniUser::getUsername, miniUser.getUsername());
        wrapper.eq(Objects.nonNull(miniUser.getPassword()), MiniUser::getPassword, miniUser.getPassword());
        return super.selectOne(wrapper);
    }

    @Override
    public Result<List<MiniUser>> selectList(MiniUser miniUser) {
        LambdaQueryWrapper<MiniUser> wrapper = new LambdaQueryWrapper<>();
        return super.selectList(wrapper);
    }

    @Override
    public PageInfo<MiniUser> selectPage(MiniUser miniUser) {
        LambdaQueryWrapper<MiniUser> wrapper = this.commonWrapper(miniUser);
        wrapper.like(Objects.nonNull(miniUser.getUsername()), MiniUser::getUsername, miniUser.getUsername());
        wrapper.like(Objects.nonNull(miniUser.getTrueName()), MiniUser::getTrueName, miniUser.getTrueName());
        wrapper.like(Objects.nonNull(miniUser.getPhone()), MiniUser::getPhone, miniUser.getPhone());
        return super.selectPage(miniUser, wrapper);
    }

    @Override
    public Result<Integer> initPassword(MiniUser miniUser) {
        return this.updateById(new MiniUser().setId(miniUser.getId()).setPassword(EncryptionUtil.getEncryption("md5", "123456")));
    }

    @Override
    public Result<Object> login(MiniUser miniUser) {
        Result<MiniUser> sysUserResult = this.selectUOne(miniUser);
        Result<Object> result = new Result<>();
        if (sysUserResult.isSuccess()) {
            miniUser = sysUserResult.getData();
            if (miniUser.getStatus() == SysConstant.DATA_DELETE_STATUS) {
                return result.setSuccess(false).setMsg("该账户已冻结").setCode(SysConstant.FREEZE_CODE_RES);
            } else {
                Long userId = miniUser.getId();
                Map<String, Object> map = new HashMap<>();
                map.put("userId", userId);
                map.put("userType", UserTypeEnum.WX_MINI_USER_TYPE.getCode());
                map.put("govIdList",miniUser.getGovIdListStr());
                map.put("govUnitIdList1",miniUser.getGovUnitIdList1Str());
                map.put("govUnitIdList2",miniUser.getGovUnitIdList2Str());
                String jti = SysUtils.getUUID();
                String jwt = JwtUtils.createJwt(jti, map, SysConstant.TOKEN_EXPIRED_TIME);
                String userToken = EncryptionUtil.getEncryptDESData(JSON.toJSONString(map), jwt);
                Map<String, Object> resMap = new HashMap<>();
                resMap.put("userToken", userToken);
                resMap.put("token", jwt);
                resMap.put("govIdList",miniUser.getGovIdListStr());
                result.setData(resMap);
                return result;
            }
        }
        return result.setMsg("账号或密码错误").setCode(SysConstant.PASSWORD_ERROR_CODE_RES);
    }

    @Override
    public Result<Integer> updatePassword(UpdatePasswordDto updatePasswordDto) {
        Result<MiniUser> result = this.selectOne(new MiniUser().setId(updatePasswordDto.getUserId()).setPassword(EncryptionUtil.getEncryption("md5", updatePasswordDto.getOldPassword())));
        if (result.isSuccess()) {
            return this.updateById(new MiniUser().setId(updatePasswordDto.getUserId()).setPassword(EncryptionUtil.getEncryption("md5", updatePasswordDto.getPassword())));
        }
        return new Result<Integer>().setSuccess(false).setMsg("原密码错误").setCode(SysConstant.PASSWORD_ERROR_CODE_RES);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<Integer> uSave(MiniUser miniUser) {
        Result<Integer> insert = this.insert(miniUser);
        if (insert.isSuccess()) {
            Long userId = miniUser.getId();
            List<MiniUserUnit> miniUserUnitList = new ArrayList<>();
            Collection<Long> govUnitIdList1 = miniUser.getGovUnitIdList1();
            if (!CollectionUtils.isEmpty(govUnitIdList1)) {
                govUnitIdList1.forEach(govUnitId -> {
                    miniUserUnitList.add(new MiniUserUnit().setUserId(userId).setGovType(1875525163790884866L).setGovUnitId(govUnitId));
                });
            }
            Collection<Long> govUnitIdList2 = miniUser.getGovUnitIdList2();
            if (!CollectionUtils.isEmpty(govUnitIdList2)) {
                govUnitIdList2.forEach(govUnitId -> {
                    miniUserUnitList.add(new MiniUserUnit().setUserId(userId).setGovType(1875525235886776321L).setGovUnitId(govUnitId));
                });
            }
            Result<Integer> integerResult = miniUserUnitService.insertBatch(miniUserUnitList);
            if (!integerResult.isSuccess()) {
                throw new MyException("更新权限失败");
            }
        }
        return insert;
    }

    @Override
    public PageInfo<MiniUser> selectUPage(MiniUser miniUser) {
        PageInfo<MiniUser> miniUserPageInfo = this.selectPage(miniUser);
        List<MiniUser> list = miniUserPageInfo.getList();
        List<Long> userIdList = new ArrayList<>();
        list.forEach(miniUser1 -> {
            userIdList.add(miniUser1.getId());
        });
        if (!CollectionUtils.isEmpty(userIdList)) {
            Result<List<MiniUserUnit>> listResult = miniUserUnitService.selectUList(new MiniUserUnit().setUserIdList(userIdList));
            if (listResult.isSuccess()) {
                List<MiniUserUnit> userUnitList = listResult.getData();
                MultiValueMap<Long, MiniUserUnit> map = new LinkedMultiValueMap<>();
                userUnitList.forEach(userUnit -> {
                    map.add(userUnit.getUserId(), userUnit);
                });
                list.forEach(miniUser1 -> {
                    miniUser1.setMiniUserUnitList(map.get(miniUser1.getId()));
                });

                list.forEach(miniUser1 -> {
                    List<MiniUserUnit> miniUserUnitList = miniUser1.getMiniUserUnitList();
                    Map<Long, Gov> govMap = new HashMap<>();
                    List<GovUnit> govUnitIdList1 = new ArrayList<>();
                    List<GovUnit> govUnitIdList2 = new ArrayList<>();
                    miniUserUnitList.forEach(miniUserUnit -> {
                        govMap.put(miniUserUnit.getGovType(), miniUserUnit.getGov());
                        if (miniUserUnit.getGovType() == 1875525163790884866L) {
                            govUnitIdList1.add(miniUserUnit.getGovUnit());
                        }
                        if (miniUserUnit.getGovType() == 1875525235886776321L) {
                            govUnitIdList2.add(miniUserUnit.getGovUnit());
                        }
                    });
                    miniUser1.setGovList(govMap.values());
                    miniUser1.setGovUnitList1(govUnitIdList1);
                    miniUser1.setGovUnitList2(govUnitIdList2);
                });
            }

        }

        return miniUserPageInfo;
    }

    @Override
    public Result<MiniUser> selectUOne(MiniUser miniUser) {
        Result<MiniUser> result = this.selectOne(miniUser);
        if (result.isSuccess()) {
            MiniUser miniUser1 = result.getData();
            Long id = miniUser1.getId();
            Result<List<MiniUserUnit>> listResult = miniUserUnitService.selectList(new MiniUserUnit().setUserId(id));
            if (listResult.isSuccess()) {
                List<MiniUserUnit> miniUserUnitList = listResult.getData();
                miniUser1.setMiniUserUnitList(miniUserUnitList);
                Set<String> govIdList = new HashSet<>();
                List<String> govUnitIdList1 = new ArrayList<>();
                List<String> govUnitIdList2 = new ArrayList<>();
                miniUserUnitList.forEach(miniUserUnit -> {
                    govIdList.add(miniUserUnit.getGovType() + "");
                    if (miniUserUnit.getGovType() == 1875525163790884866L) {
                        govUnitIdList1.add(miniUserUnit.getGovUnitId() + "");
                    }
                    if (miniUserUnit.getGovType() == 1875525235886776321L) {
                        govUnitIdList2.add(miniUserUnit.getGovUnitId() + "");
                    }
                });
                miniUser1.setGovIdListStr(govIdList);
                miniUser1.setGovUnitIdList1Str(govUnitIdList1);
                miniUser1.setGovUnitIdList2Str(govUnitIdList2);
            }
        }
        return result;
    }

    @Override
    public Result<Integer> uUpdateById(MiniUser miniUser) {
        Result<Integer> integerResult = this.updateById(miniUser);
        Long userId = miniUser.getId();
        if(integerResult.isSuccess()){
            Result<List<MiniUserUnit>> listResult = miniUserUnitService.selectList(new MiniUserUnit().setUserId(miniUser.getId()));
            if (listResult.isSuccess()) {
                List<MiniUserUnit> miniUserUnitList1 = listResult.getData();
                List<Long> miniUserUnitIdList = new ArrayList<>();
                miniUserUnitList1.forEach(miniUserUnit -> {
                    miniUserUnitIdList.add(miniUserUnit.getId());
                });
                if(!CollectionUtils.isEmpty(miniUserUnitIdList)){
                    miniUserUnitService.deleteBatchIds(miniUserUnitIdList);
                }
                List<MiniUserUnit> miniUserUnitList = new ArrayList<>();
                Collection<Long> govUnitIdList1 = miniUser.getGovUnitIdList1();
                if (!CollectionUtils.isEmpty(govUnitIdList1)) {
                    govUnitIdList1.forEach(govUnitId -> {
                        miniUserUnitList.add(new MiniUserUnit().setUserId(userId).setGovType(1875525163790884866L).setGovUnitId(govUnitId));
                    });
                }
                Collection<Long> govUnitIdList2 = miniUser.getGovUnitIdList2();
                if (!CollectionUtils.isEmpty(govUnitIdList2)) {
                    govUnitIdList2.forEach(govUnitId -> {
                        miniUserUnitList.add(new MiniUserUnit().setUserId(userId).setGovType(1875525235886776321L).setGovUnitId(govUnitId));
                    });
                }
                Result<Integer> integerResult2 = miniUserUnitService.insertBatch(miniUserUnitList);
                if (!integerResult2.isSuccess()) {
                    throw new MyException("更新权限失败");
                }
            }

        }
        return integerResult;
    }

    @Override
    public Result<Integer> removeById(Serializable id) {
        MiniUser miniUser = new MiniUser().setStatus(SysConstant.DATA_DELETE_STATUS)
                .setId((Long) id);
        return this.updateById(miniUser);
    }

}